/**
 * 
 */
package net.penguinmenac3.archivedb;

import java.util.LinkedList;
import java.util.StringTokenizer;

/**
 * @author Michael
 * 
 */
class SearchEngine {
	EntryLoader el = new EntryLoader();
	SearchEntry[] search_entries = null;

	SearchEngine() {
		update();
	}

	void update() {
		search_entries = el.getSearchEntries();
	}

	private double complexCompare(String a, String b) {
		double result = 0;
		if (a.equals(b)) {
			result = 1.0;
		} else if (b.contains(a)) {
			double dif = ((b.length() - a.length()) / (double) b.length());
			result = 1.0 - dif;
		} else if (a.contains(b)) {
			double dif = ((a.length() - b.length()) / (double) a.length());
			result = 1.0 - dif;
		} else {
			result = StringOperator.similarity(a, b);
		}
		return result;
	}

	private double textCompare(String a, String b) {
		double result = 0;
		if (b.contains(a)) {
			result = 1;
		}
		return result;
	}

	Entry[] search(String[] keywords, int filetype) {
		LinkedList<Entry> result = new LinkedList<Entry>();
		for (SearchEntry se : search_entries) {
			if (se.filetype != filetype && filetype != -1 && se.filetype != -1) {
				continue;
			}
			double complex = 0;
			for (String k : keywords) {
				for (String i : se.keywords) {
					complex += complexCompare(k, i);
				}
				// only keywords is count fully others are made weaker
				complex += complexCompare(k, se.filename)*0.8;
				complex += complexCompare(k, se.description)*0.8;
			}
			if (complex > 0.1) {
				// an important formula for the evaluation
				double relevance = complex / (double) keywords.length;
				Entry e = el.completeEntry(se, relevance, false);
				result.add(e);
			}
		}
		return result.toArray(new Entry[0]);
	}

	Entry[] searchFulltext(String[] keywords, int filetype) {
		LinkedList<Entry> result = new LinkedList<Entry>();
		for (SearchEntry se : search_entries) {
			if (se.filetype != filetype && filetype != -1 && se.filetype != -1) {
				continue;
			}
			Entry e = el.completeEntry(se, 0, true);
			double complex = 0;
			for (String k : keywords) {
				for (String i : e.keywords) {
					complex += complexCompare(k, i);
				}
				// only keywords is count fully others are made weaker
				complex += complexCompare(k, e.filename)*0.8;
				complex += complexCompare(k, e.description)*0.8;
				// fulltextsearch is worth less than other searches
				complex += textCompare(k, e.fulltext)*0.5;
			}
			if (complex > 0.1) {
				// an important formula for the evaluation
				double relevance = complex / (double) keywords.length;
				e.relevance = relevance;
				result.add(e);
			}
		}
		return result.toArray(new Entry[0]);
	}

	Key[] getMoreKeywords(String[] keywords, int filetype) {
		// get all fitting entries
		Entry[] entries = search(keywords, filetype);

		// destinct
		LinkedList<String> result = new LinkedList<String>();
		for (Entry e : entries) {
			for (String k : e.keywords) {
				boolean exists = false;
				for (String i : result.toArray(new String[0])) {
					if (i.equals(k)) {
						exists = true;
					}
				}
				if (!exists) {
					result.add(k);
				}
			}
		}

		String[] results = result.toArray(new String[0]);
		LinkedList<Key> out = new LinkedList<Key>();
		// count times the results occur
		for (String r : results) {
			int counter = 0;
			for (Entry e : entries) {
				for (String k : e.keywords) {
					if (k.equals(r)) {
						counter++;
					}
				}
			}
			out.add(new Key(r, counter));
		}

		return out.toArray(new Key[0]);
	}

}
